package reserve
import (
    "time"
	"strings"
	"errors"
	"dhfshop/models"
	//"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"dhfshop/models/consts"
)

//预约周期管理
type Period struct {
	PeriodId    int64       `orm:"column(period_id);pk;auto" json:"period_id" form:"period_id"`
	PartnerId   int64         `orm:"column(partner_id)" json:"partner_id" form:"partner_id"`     //商户ID
	Schema      *Schema     `orm:"column(schema_id);rel(fk);on_delete(cascade)" json:"-" form:"-"` //级联删除
	SchemaId    int64       `orm:"-" json:"schema_id" form:"schema_id"`
	Name        string      `orm:"column(name);size(128);null" json:"name" form:"name"`       //名称,比如:周一、周二...
	Status      int         `orm:"column(status)" json:"status" form:"status"` 
	SourceAt    time.Time   `orm:"column(source_at);type(date)" json:"-" form:"-"`       //号源时间,只要日期到天
    SourceAtStr string      `orm:"-" json:"source_at" form:"source_at"`
	Timeslots   []*Timeslot `orm:"reverse(many)" json:"timeslots" form:"-"`
}

func (u *Period) TableUnique() [][]string {
	return [][]string{
		[]string{"Schema", "SourceAt"},
	}
}

func init() {
	orm.RegisterModel(new(Period))
}

func AddPeriod(m *Period) (id int64, err error) {
	o := models.GetDefaultDB()
	id, err = o.Insert(m)
	return
}

func AddMultiPeriods(list []*Period) (err error) {
	size := len(list)
	o := models.GetDefaultDB()
	if size > 1 {
	    _, err = o.InsertMulti(size, list) 
	}else{
	   _, err = o.Insert(list[0])
	}
	return
}

func GetPeriodById(id int64) (v *Period, err error) {
	o := models.GetDefaultDB()
	v = &Period{PeriodId: id}
	if err = o.Read(v); err == nil {
		v.SchemaId = v.Schema.SchemaId
		v.SourceAtStr = v.SourceAt.Format(consts.DATE_FORMAT)
		v.Schema = nil
		return v, nil
	}
	return nil, err
}

func GetAllPeriods(start,end string,query map[string]string,fields []string,order_by map[string]string,offset int,limit int)([]*Period, int64,error) {
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(Period))
	if len(start) == 10 {
	    if start_time, err := time.Parse(consts.DATE_FORMAT,start); err == nil {
			qs = qs.Filter("source_at__gte", start_time)
		}
	}
	if len(end) == 10 {
	   if end_time, err := time.Parse(consts.DATE_FORMAT,end); err == nil {
			qs = qs.Filter("source_at__lte", end_time)
	   }
	}
	for k, v := range query {
		k = strings.Replace(k, ".", "__", -1)
		qs = qs.Filter(k, v)
	}
	cnt, err := qs.Count()
	var sortFields []string
	for k, v := range order_by {
		orderby := ""
		if v == "desc" {
			orderby = "-" + k
		} else if v == "asc" {
			orderby = k
		} else {
			return nil, 0, errors.New("Error: Invalid order. Must be either [asc|desc]")
		}
		sortFields = append(sortFields, orderby)
	}
	var lists []*Period
	qs = qs.OrderBy(sortFields...)
	if _, err := qs.Limit(limit, offset).All(&lists, fields...); err == nil {
		for _, period := range lists {
		    o.LoadRelated(period, "Timeslots")
			for _, timeslot := range period.Timeslots {   
				timeslot.Schema = nil
				timeslot.Period = nil
		    }
			period.SchemaId = period.Schema.SchemaId
            period.SourceAtStr = period.SourceAt.Format(consts.DATE_FORMAT)
		    period.Schema = nil
		}
		return lists, cnt, nil
	}
	return nil, 0, err
}

func GetPeriodIdByDate(sourceAt time.Time, schemaId int64)(periodId int64, err error) {
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(Period))
	qs = qs.Filter("source_at__gte", sourceAt)
	qs = qs.Filter("source_at__lte", sourceAt)
	qs = qs.Filter("schema_id", schemaId)
	period := new(Period)
	if err = qs.One(period); err == nil {
		return period.PeriodId, nil
	}
	return -1, err
}

func GetPeriodIdsByDate(partnerId,schemaId int64,startAt,endAt time.Time)(periodIds []int64, err error) {
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(Period))
	qs = qs.Filter("partner_id", partnerId)
	qs = qs.Filter("schema_id", schemaId)
	qs = qs.Filter("source_at__gte", startAt)
	qs = qs.Filter("source_at__lte", endAt)
	var lists []*Period
	if _, err = qs.All(&lists); err == nil {
		for _, period := range lists {
			periodIds = append(periodIds, period.PeriodId)
	    }
		return
	}
	return
}

func UpdatePeriodById(m *Period, k ...string) (err error) {
	o := models.GetDefaultDB()
	v := Period{PeriodId: m.PeriodId}
	if err = o.Read(&v); err != nil {
		return err
	}else{
	    if _, err = o.Update(m, k...); err != nil {
		   return err
		}
	}
	return nil
}

func DeletePeriodById(id int64) (err error) {
	o := models.GetDefaultDB()
	v := Period{PeriodId: id}
	if err = o.Read(&v); err == nil {
		if _, err = o.Delete(&v); err == nil {
			return nil
		}
	}
	return
}

func DeletePeriodsByMultiCond(partnerId,schemaId,periodId int64,start,end string) (err error) {
    o := models.GetDefaultDB()
	qs := o.QueryTable(new(Period))
	qs = qs.Filter("partner_id", partnerId)
	if schemaId > 0 {
	   qs = qs.Filter("schema_id", schemaId)
	}
	if periodId > 0 {
	   qs = qs.Filter("period_id", periodId)
	}
	if len(start) == 10 && len(end) == 10 {
		if startAt, err := time.Parse(consts.DATE_FORMAT,start); err == nil {
			if endAt, err := time.Parse(consts.DATE_FORMAT,end); err == nil {
			    qs = qs.Filter("source_at__gte", startAt)
	            qs = qs.Filter("source_at__lte", endAt)
	        }
		}  
	}
	_, err = qs.Delete()
	return
}
